<script lang="ts" setup>
import { Button, Modal, Table } from 'ant-design-vue'
import dayjs from 'dayjs'
import JsonEditorVue from 'json-editor-vue'
import type { IBasicWithPage } from '~/types/apis/basic'
import type { AfterFetchContext } from '@vueuse/core'
import type { ColumnsType } from 'ant-design-vue/es/table'
import type { IReportDetails } from '~/types/apis/report'
import { ref, onMounted, reactive } from 'vue'
import { Row, Col, Card } from 'ant-design-vue'
import * as echarts from 'echarts';
import { useRoute, useRouter } from 'vue-router';
import ReportComparison from './ReportComparison.vue'
import ReportDetailExpand from './ReportDetailExpand.vue'
import { keepDigitDecimal } from '~/utils/internal'

defineProps<{
    columns: ColumnsType
}>()

const route = useRoute()
const pageConfig = reactive<{
    page: number
    size: number
    reportId: number | undefined
    type: string
    engineType: string
    totalSize: number
}>({
    page: 1,
    size: 8,
    reportId: undefined,
    type: 'STRESS',
    engineType: 'API',
    totalSize: 0,
})

const router = useRouter()
const modalOpen = ref<boolean>()
const modalContent = ref<Record<string, any>>({})
const echartsRef = ref(null);
const screenshotModalOpen = ref<boolean>()
const screenshotFileUrl = ref<string>('')
const comparisonModal = ref<boolean>()
const comparisonModalContent = ref<Record<string, any>>({})
const interval = ref<number>()

// 成功数量
const successCount = ref(0);
// 失败数量
const failCount = ref(0);
// 通过率
const passingRate = ref("0.00");
// 用例总数
const caseCount = ref(0);
// 消耗时间
const timeConsuming = ref("0.00");
// 摘要内容
const summary = ref({
    '最大响应时间(毫秒)': 0,
    '最小响应时间(毫秒)': 0,
    '平均响应时间(毫秒)': 0.00,
    'QPS': 0.00,
    '错误请求百分比': 0.00,
});
const executeScreentshotUrl = computed(
    () =>
        `/engine-service/api/v1/file/get_temp_url?fileUrl=${screenshotFileUrl.value}`,
)

// 筛选API类型用例数量
const filterAPICount = ref(0);
// 筛选UI类型用例数量
const filterUICount = ref(0);
// 筛选DB类型用例数量
const filterDBCount = ref(0);
// 筛选断言类型用例数量
const filterAssertionCount = ref(0);
// 原生数据
const originData = ref(null);
let {
    post,
    data: dataSource,
    isFetching,
} = useCustomFetch<IReportDetails[]>(
    '/data-service/api/v1/report_detail/page',
    {
        immediate: false,
        initialData: [],
        afterFetch: (ctx: AfterFetchContext<IBasicWithPage<IReportDetails>>) => {
            if(pageConfig.type === 'STRESS' && ctx.data.code === 401){
                clearInterval(interval.value)
                return;
            }
            if (ctx.data && ctx.data.code === 0) {
                pageConfig.totalSize = ctx.data.data.total_record;

                // 统计成功，失败数量
                const jsonResData: IReportDetails[] = ctx.data.data.current_data;
                originData.value = jsonResData;
                successCount.value = jsonResData.filter(item => item.assertionState && item.executeState).length;
                failCount.value = jsonResData.filter(item => !item.assertionState || !item.executeState).length;
                // 通过率
                passingRate.value = (successCount.value / ((successCount.value + failCount.value)) * 100).toFixed(2)
                // 用例总数
                caseCount.value = jsonResData.length
                // 消耗总时间
                timeConsuming.value = route.query.timeConsuming !== 'null' ? (Number(route.query.timeConsuming) / 1000).toFixed(2) : '0.00'
                // 刷新环形图表，使数据绑定上
                echartsInit();
                // API类型
                filterAPICount.value = jsonResData.filter(item => item.type === 'API').length;
                // UI类型
                filterUICount.value = jsonResData.filter(item => item.type === 'UI').length;
                // DB类型
                filterDBCount.value = jsonResData.filter(item => item.type === 'DATABASE').length;
                if (route.query.type === "MIX" || route.query.type === "UI") {
                    // 断言类型
                    filterAssertionCount.value = jsonResData.filter(item => item.operationType !== null && item.operationType.startsWith("ASSERTION")).length;
                }

                return {
                    data: ctx.data.data.current_data,
                    response: ctx.response,
                }
            }
            return {
                data: [],
                response: ctx.response,
            }
        },
    },
)

const { data: screentshotUrl, execute: getScreenshotUrl } =
    useCustomFetch<string>(executeScreentshotUrl, {
        immediate: false,
        initialData: '',
        afterFetch(ctx) {
            return {
                data: ctx.data.data,
                response: ctx.response,
            }
        },
    })

async function reFetch() {
    await nextTick()
    post(toRaw(pageConfig)).execute()
}


onMounted(() => {

    if (route.query.id) {
        pageConfig.reportId = Number(route.query.id)
        pageConfig.type = route.query.type as string
    }
    if (route.query.summary.value !== 'null') {
        summary.value = JSON.parse(route.query.summary)
    }
    reFetch()
    echartsInit()

    if (pageConfig.type === 'STRESS') {
        interval.value = setInterval(reFetch, 500)
    }
})

onUnmounted(() => {
    if (pageConfig.type === 'STRESS') {
        clearInterval(interval.value)
    }
})


const echartsInit = () => {
    const chart = echarts.init(echartsRef.value);
    const option = {
        color: ['#1DDD75', '#ED4646'],
        tooltip: {
            trigger: 'item'
        },
        legend: {
            top: 'center',
            right: 40,
            orient: 'vertical',
            itemGap: 20,
            icon: 'circle',
            textStyle: {
                color: '#999999',
            },
        },
        series: [
            {
                name: '用例统计',
                type: 'pie',
                radius: ['40%', '70%'],
                center: ['35%', '50%'],
                startAngle: 0,
                endAngle: 360,
                label: {
                    color: '#999999',
                    overflow: 'none'
                },
                data: pageConfig.type === 'STRESS' ? [
                    { value: summary.value ? (100 - summary.value['错误请求百分比'].toFixed(2) * 100) : 0, name: '成功率' },
                    { value: summary.value ? summary.value['错误请求百分比'].toFixed(2) * 100 : 0, name: '失败率' }
                ] : [
                    { value: successCount.value, name: '成功案例' },
                    { value: failCount.value, name: '失败案例' }
                ]
            }
        ]
    };
    chart.setOption(option);
}




// 过滤数据 
const filterData = (type: number) => {
    if (type == 1) {
        // 成功
        dataSource.value = originData.value.filter((item: IReportDetails) => item.assertionState && item.executeState)
    } else if (type == 2) {
        // 失败
        dataSource.value = originData.value.filter((item: IReportDetails) => !item.assertionState || !item.executeState)
    } else if (type == 3) {
        // API
        dataSource.value = originData.value.filter((item: IReportDetails) => item.type === 'API')
    } else if (type == 4) {
        // UI
        dataSource.value = originData.value.filter((item: IReportDetails) => item.type === 'UI')
    } else if (type == 5) {
        // DB
        dataSource.value = originData.value.filter((item: IReportDetails) => item.type === 'DATABASE')
    } else if (type == 6) {
        dataSource.value = originData.value.filter((item: IReportDetails) => item.operationType !== null && item.operationType.startsWith("ASSERTION"))
    } else {
        // 全部
        dataSource.value = originData.value
    }
}

const requestConfigStore = useRequestConfigStore()

const comparisonCancel = () => {
    // 当api组件出现打开或者关闭状态时， 请求table相关组件tab下标需要重置
    // 因为在requestConfig组件中无法监听到状态的改变，所以在这里进行初始化
    requestConfigStore.setChangeActiveKey('head')
}

const codeModalVisible = ref(false)
const selectStep = ref(null)

const handleOpenCodeModal = (record: IReportDetails) => {
    codeModalVisible.value = true
    selectStep.value = record
}

const expanddata = reactive<any>({
    expandedRowKeys: [],
})
const onExpand = (record: any) => {
    modalContent.value = record
    const set = new Set(expanddata.expandedRowKeys);
    if (set.has(record.id)) {
        set.delete(record.id)
    } else {
        set.add(record.id)
    }
    expanddata.expandedRowKeys = [...set]
}




</script>

<template>
    <div>
        <Row class="row" :gutter="16" v-if='pageConfig.type === "STRESS"'>
            <Col :span="16">
            <Row :gutter="16">
                <Col :span="8">
                <Card class="card card4">
                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                {{ summary ? keepDigitDecimal((100 - keepDigitDecimal(summary['错误请求百分比'] * 100, 2)), 2) : 0
                                }}<span>%</span>
                            </div>
                            <div class="card__title">
                                通过率
                            </div>
                        </div>
                        <img src="../../assets/images/wancheng.png" alt="">
                    </div>
                </Card>
                </Col>
                <Col :span="8">
                <Card class="card card3">
                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                <div class="card__data">
                                    {{ summary ? summary['最大响应时间(毫秒)'] : 0 }}<span>ms</span>
                                </div>
                            </div>
                            <div class="card__title">
                                最大响应时间
                            </div>
                        </div>
                        <img src="../../assets/images/zongshu.png" alt="">
                    </div>
                </Card>
                </Col>
                <Col :span="8">
                <Card class="card card2">
                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                <div class="card__data">
                                    {{ summary ? summary['最小响应时间(毫秒)'] : 0 }}<span>ms</span>
                                </div>
                            </div>
                            <div class="card__title">
                                最小响应时间
                            </div>
                        </div>
                        <img src="../../assets/images/chenggonglv.png" alt="">
                    </div>
                </Card>
                </Col>
            </Row>
            <Row style="margin-top: 12px;" :gutter="16">
                <Col :span="8">
                <Card class="card card1" flex justify-between items-center>
                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                <div class="card__data">
                                    {{ summary ? keepDigitDecimal(summary['平均响应时间(毫秒)'], 2) : '0.00' }}<span>ms</span>
                                </div>
                            </div>
                            <div class="card__title">
                                平均响应时间
                            </div>
                        </div>
                        <img src="../../assets/images/haoshi.png" alt="">
                    </div>
                </Card>
                </Col>

                <Col :span="8">
                <Card class="card card5">
                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                <div class="card__data">
                                    {{ summary ? keepDigitDecimal(summary['QPS'], 2) : '0.00' }}
                                </div>
                            </div>
                            <div class="card__title">
                                QPS
                            </div>
                        </div>
                        <img src="../../assets/images/chenggongshu.png" alt="">
                    </div>
                </Card>
                </Col>

                <Col :span="8">
                <Card class="card card6">

                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                {{ summary ? keepDigitDecimal(summary['错误请求百分比'] * 100, 2) : 0 }}<span>%</span>
                            </div>
                            <div class="card__title">
                                错误请求百分比
                            </div>
                        </div>
                        <img src="../../assets/images/shibai.png" alt="">
                    </div>

                </Card>
                </Col>


            </Row>
            </Col>
            <Col :span="8">
            <Card class="card-echart">
                <div ref="echartsRef" style="width: 100%;height: 100%"> </div>
            </Card>
            </Col>
        </Row>
        <Row class="row" :gutter="16" v-else>
            <Col :span="16">
            <Row :gutter="16">
                <Col :span="8">
                <Card class="card card1" flex justify-between items-center>
                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                {{ timeConsuming }} <span>秒</span>
                            </div>
                            <div class="card__title">
                                耗时
                            </div>
                        </div>
                        <img src="../../assets/images/haoshi.png" alt="">
                    </div>
                </Card>
                </Col>
                <Col :span="8">
                <Card class="card card2">
                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                {{ passingRate }} <span>%</span>
                            </div>
                            <div class="card__title">
                                通过率
                            </div>
                        </div>
                        <img src="../../assets/images/chenggonglv.png" alt="">
                    </div>
                </Card>
                </Col>
                <Col :span="8">
                <Card class="card card3">

                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                {{ caseCount }}
                            </div>
                            <div class="card__title">
                                用例总数
                            </div>
                        </div>
                        <img src="../../assets/images/zongshu.png" alt="">
                    </div>
                </Card>
                </Col>

            </Row>
            <Row style="margin-top: 12px;" :gutter="16">
                <Col :span="8">
                <Card class="card card4">

                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                {{ caseCount }}
                            </div>
                            <div class="card__title">
                                完成数
                            </div>
                        </div>
                        <img src="../../assets/images/wancheng.png" alt="">
                    </div>

                </Card>
                </Col>
                <Col :span="8">
                <Card class="card card5">
                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                {{ successCount }}
                            </div>
                            <div class="card__title">
                                成功数
                            </div>
                        </div>
                        <img src="../../assets/images/chenggongshu.png" alt="">
                    </div>
                </Card>
                </Col>

                <Col :span="8">
                <Card class="card card6">

                    <div flex justify-between items-center>
                        <div>
                            <div class="card__data">
                                {{ failCount }}
                            </div>
                            <div class="card__title">
                                失败数
                            </div>
                        </div>
                        <img src="../../assets/images/shibai.png" alt="">
                    </div>

                </Card>
                </Col>


            </Row>
            </Col>
            <Col :span="8">
            <Card class="card-echart">
                <div ref="echartsRef" style="width: 100%;height: 100%"> </div>
            </Card>
            </Col>
        </Row>
        <div flex justify-between mt-10 mb-5>
            <Row align="middle" mb-6 flex class="row2">
                <template v-if="pageConfig.type !== 'STRESS'">
                    <Col :span="2"><span @click="filterData(0)" class="all">全部({{ caseCount }})</span></Col>
                    <Col :span="2"><span @click="filterData(1)" class="success">成功({{ successCount }})</span></Col>
                    <Col :span="2"><span @click="filterData(2)" class="fail">失败({{ failCount }})</span></Col>
                </template>
                <Col :span="2" v-if="pageConfig.type === 'MIX'"><span @click="filterData(3)" class="default">api类型({{
                    filterAPICount
                }})</span></Col>
                <Col :span="2" v-if="pageConfig.type === 'MIX'"><span @click="filterData(4)" class="default">ui类型({{
                    filterUICount
                }})</span></Col>
                <Col :span="2" v-if="pageConfig.type === 'MIX'"><span @click="filterData(5)" class="default">db类型({{
                    filterDBCount
                }})</span></Col>
                <Col :span="2" v-if="pageConfig.type === 'MIX' || pageConfig.type === 'UI'"><span @click="filterData(6)"
                    class="default">断言({{ filterAssertionCount }})</span>
                </Col>
            </Row>
            <Button float-right @click="router.back()">返回</Button>
        </div>


        <Modal v-model:open="modalOpen" :footer="null" width="80%">
        </Modal>

        <Modal v-model:open="screenshotModalOpen" :footer="null" width="50%">
            <div b="~ solid #333" my-8 w-full rounded>
                <a :href="screentshotUrl ?? ''" target="_blank">
                    <img :src="screentshotUrl ?? ''" style="width: 100%; height: 100%">
                </a>
            </div>
        </Modal>

        <Modal v-model:open="comparisonModal" :footer="null" width="80%" @cancel="comparisonCancel">
            <ReportComparison :content="comparisonModalContent" :page-type="pageConfig.type"></ReportComparison>
        </Modal>
        <!-- 断言详情table列表 -->
        <!-- :loading="isFetching" -->
        <Table class="mytable" :columns="columns" :data-source="dataSource?.length ? dataSource : []" :scroll="{ x: 1500 }"
            :pagination="false" :expand-column-width="100" :row-key="record => record.id"
            :expandedRowKeys="expanddata.expandedRowKeys" :expandIcon="() => null">
            <template #expandedRowRender="{ record }">
                <ReportDetailExpand :data="record" :page-config="pageConfig" />
            </template>
            <template #bodyCell="{ column, record, value }">
                <slot :column="column" :record="record" />
                <template v-if="['gmtCreate', 'gmtModified'].includes(column.key!.toString())">
                    {{
                        dayjs(record[column.key as string]).format('YYYY-MM-DD - HH:mm:ss')
                    }}
                </template>
                <template v-else-if="column.key?.toString() === 'function'">
                    <Button type="primary" size="small" class="mx-3" my-3 @click="onExpand(record)">
                        查看详情
                    </Button>
                    <Button type="primary" size="small" class="mx-3" my-3
                        @click="handleOpenCodeModal(record as IReportDetails)" style="background: #35A97B "
                        v-if="pageConfig.type === 'UI' || pageConfig.type === 'MIX'"
                        :disabled="record.type !== 'UI' && pageConfig.type != 'UI'">
                        查看代码
                    </Button>
                    <Button v-if="pageConfig.type !== 'STRESS'" type="primary" size="small" style="background: #587CEA"
                        @click="() => {
                            comparisonModal = true
                            comparisonModalContent = record
                        }
                            ">
                        配置对比
                    </Button>
                </template>

                <template v-else-if="column.key === 'isContinue' || column.key === 'isScreenshot'
                    ">
                    {{ value ? '是' : '否' }}
                </template>

                <template v-else-if="column.key === 'screenshotUrl'">
                    <Button v-if="value" type="primary" size="small" @click="() => {
                        screenshotModalOpen = true
                        screenshotFileUrl = value
                        getScreenshotUrl()
                    }
                        ">
                        查看
                    </Button>
                    <span v-else> - </span>
                </template>

                <template v-else-if="typeof value === 'boolean'">
                    <div font-bold>
                        <ExecuteState :model-value="value" />
                    </div>
                </template>

                <template v-else-if="value">
                    <p truncate>{{ value }}</p>
                </template>

                <template v-else-if="value == null || value === ''"> - </template>
            </template>
        </Table>
    </div>
    <CodeModal v-model:code-modal-visible="codeModalVisible" :step="selectStep"></CodeModal>
</template>


<style lang="scss" scoped>
img {
    width: 70px;
    height: 70px;
}

:deep(.ant-card-body) {
    padding: 28px !important;
    width: 100%;
    height: 100%
}

:deep(.ant-table .ant-table-expand-icon-col) {
    width: 0 !important;
    /* 如果有需要，也可以添加其他CSS属性来隐藏内容 */
    visibility: hidden;
    padding: 0 !important;
    /* 注意：这可能会影响到布局和响应式表现，所以需要谨慎使用 */
}

:deep(.mytable .ant-table-container table>thead>tr:first-child >*:nth-child(2)) {
    border-start-start-radius: 8px
}

:deep(.mytable2 .ant-table-container table>thead>tr:first-child >*:nth-child(2)) {
    border-start-start-radius: 0px
}

.ant-card-bordered {
    border: none;
}

.row {
    margin-bottom: 20px;
}

.card {
    height: 145px;


    &__data {
        font-size: 36px;
        color: var(--text-color);

        span {
            font-size: 16px;
        }
    }

    &__title {
        font-size: 16px;
        margin-top: 6px;
    }
}


.card1 {
    border-left: 2px solid #6646ED;

    .card__title {
        color: #6646ED;
    }
}

.card2 {
    border-left: 2px solid #9946ED;

    .card__title {
        color: #9946ED;
    }

}

.card3 {
    border-left: 2px solid #39E7FF;

    .card__title {
        color: #39E7FF;
    }

}

.card4 {
    border-left: 2px solid #33A879;

    .card__title {
        color: #33A879;
    }
}


.card5 {
    border-left: 2px solid #1DDD75;

    .card__title {
        color: #1DDD75;
    }
}


.card6 {
    border-left: 2px solid #ED4646;

    .card__title {
        color: #ED4646;
    }
}

.row2 {
    flex: 1;
}

.row2 span {
    font-size: 16px;
    cursor: pointer;
    -webkit-user-select: none;
    /*谷歌 /Chrome*/
    -moz-user-select: none;
    /*火狐/Firefox*/
    -ms-user-select: none;
    /*IE 10+*/
    user-select: none;
}

.card-echart {
    width: 100%;
    height: 100%;
}

.all {
    color: #39E7FF;
}

.success {
    color: #1DDD75;
}

.fail {
    color: #ED4646;
}

.default {
    color: #90AFFF;
}
</style>